home *** CD-ROM | disk | FTP | other *** search
- PROGRAM doom1;
- {
- DOOM engine, version 0.00001
- - by Bjarke Viksφe
- nov 1994
-
- Actually, this is pretty much based on the idea from the CYBERSPACE
- sources by Phantom/Nostalgia.
- This one was build by expanding my floor routines...
- and I will add some textured walls later ;)
- }
-
- {$A+,B-,G+,E+,I+,N-,X+}
- {$C FIXED PRELOAD PERMANENT}
-
- USES
- DEMOINIT,MOUSE,ILBM256,PICTURE;
-
- {{$DEFINE DEBUG}
-
- TYPE
- pBunk = ^BunkArray;
- BunkArray = ARRAY[0..254, 0..255] of byte;
- pIntegerArray = ^IntegerArray;
- IntegerArray = ARRAY[0..32760] of integer;
-
- CONST
- LINES = 70; {how many lines shall we paint}
- TILT = 31780; {tilt floor how much?}
-
- VAR
- map, tiles : pBunk;
- LineTable : array[1..3] of pIntegerArray;
- xpos,ypos, angle : word;
- CoordPtr : array[0..255] of pointer;
- SinusTable : array[0..639] of integer;
-
- {DOOM draw private variables}
- VAR
- tablepos : word;
- height : word;
- CONST
- {table that describes how the colours fades away...}
- colourtable : array[1..LINES] of byte =
- (224,224,224,224,
- 192,192,192,192,192,192,
- 160,160,160,160,160,160,160,
- 128,128,128,128,128,128,128,128,
- 96,96,96,96,96,96,96,96,
- 64,64,64,64,64,64,64,64,64,
- 32,32,32,32,32,32,32,32,32,32,
- 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0);
-
-
-
- (*------------------------------------------------*)
-
- procedure SetupSinus;
- var
- i : integer;
- v, vadd : real;
- begin
- v:=0.0;
- vadd:=(2.0*pi/512.0);
- for i:=0 to 639 do begin
- SinusTable[i]:=round(sin(v)*32767);
- v:=v+vadd;
- end;
- end;
-
- procedure SetColours;
- {Setup ugly colours}
- var
- i,j,k,fac : integer;
- begin
- {calc 8 shades of our 32 colours}
- k:=1;
- fac:=256;
- for i:=1 to 8 do begin
- for j:=1 to (32*3) do begin
- CMAP[k]:=(CMAP[j] * fac) DIV 256;
- inc(k);
- end;
- dec(fac,31);
- end;
- SetCMAP;
- end;
-
-
- procedure CreateMap;
- var
- charmap : array[#0..#128] of byte;
- {Create map.
- Characters in string are indexes to tiles! 'a' is tile #0,
- 'b' is #1 (red one) and so...}
- procedure Strip(ypos : integer; st : string);
- var j : integer;
- begin
- for j:=1 to length(st) do st[j]:=char(charmap[st[j]]);
- Move(st[1],map^[ypos,1],length(st));
- end;
- var
- c : char;
- begin
- GetMem(map,65535);
- FillChar(map^,65535,#0);
-
- charmap[' ']:=0;
- for c:='a' to 'z' do charmap[c]:=ord(c)-ord('a');
- for c:='A' to 'Z' do charmap[c]:=ord(c)-ord('A');
-
- {ceiling}
- Strip(148,' bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb ');
- Strip(149,' bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb ');
- Strip(150,' bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb ');
- Strip(151,' bbb ');
- Strip(152,' bbb ');
- Strip(153,' bbb ');
- Strip(154,' bbb ');
- Strip(155,' bbb ');
- Strip(156,' bbb ');
- Strip(157,' bbb ');
- Strip(158,' bbb ');
- Strip(159,' bbb ');
- Strip(160,' bbb ');
- Strip(161,' bbbeeeee ');
- Strip(162,' bbbeeeee ');
- Strip(163,' bbbeeeee ');
- {floor}
- Strip( 20,' cdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdc ');
- Strip( 21,' dcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcd ');
- Strip( 22,' cdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdc ');
- Strip( 23,' dcd ggg ');
- Strip( 24,' cdc ggg ');
- Strip( 25,' dcd ggg ');
- Strip( 26,' cdc ');
- Strip( 27,' dcd ');
- Strip( 28,' cdc ');
- Strip( 29,' dcd ');
- Strip( 30,' cdc ');
- Strip( 31,' dcd ');
- Strip( 32,' cdc ');
- Strip( 33,' dcdffff ');
- Strip( 34,' cdcffff ');
- Strip( 35,' dcdffff ');
- end;
-
- procedure CreateTiles;
- {Build the tiles. Load .lbm graphics picture}
- var
- i,j,k : word;
- begin
- GetMem(tiles,65535);
- FillChar(tiles^,65535,#0);
-
- LoadPix(pScreen(tiles),'doomgfx1.lbm');
- {picture is 320x200. Need to convert it to 256x128}
- j:=0; k:=0;
- for i:=1 to 200 do begin
- Move(pscreen(tiles)^[j],pScreen(tiles)^[k],256);
- inc(j,320);
- inc(k,256);
- end;
- end;
-
-
- procedure PrecalcLines;
- {Precalc rotated floor-lines data}
- const
- XPOS = 15; {this will ajust the height of the viewer}
- var
- q,p,i, x1,y1,x2,y2 : integer;
- z,sin1,cos1 : integer;
- pos,angle : word;
- cx,cy : longint;
- begin
- for i:=1 to 3 do GetMem(LineTable[i],65535);
-
- p:=1;
- pos:=0;
- angle:=0;
- for q:=0 to 255 do begin
- CoordPtr[q]:=@LineTable[p]^[pos];
-
- z:=31100;
- sin1:=SinusTable[angle];
- cos1:=SinusTable[angle+128];
- for i:=1 to LINES do begin
- x1:=LongDiv(-XPOS*65536,z); {calc first coord}
- y1:=LongDiv((i)*longint(TILT),z);
- cx := (LongMul(x1,cos1) - LongMul(y1,sin1)) DIV 32768; {rotate it}
- cy := (LongMul(x1,sin1) + LongMul(y1,cos1)) DIV 32768;
- x1:=cx;
- y1:=cy;
- LineTable[p]^[pos]:=x1;
- LineTable[p]^[pos+1]:=y1;
-
- x2:=LongDiv(XPOS*65535,z); {calc second coord}
- y2:=LongDiv((i)*longint(TILT),z);
- cx := (LongMul(x2,cos1) - LongMul(y2,sin1)) DIV 32768; {rotate it}
- cy := (LongMul(x2,sin1) + LongMul(y2,cos1)) DIV 32768;
- x2:=cx;
- y2:=cy;
- LineTable[p]^[pos+2]:=(longint(x2-x1) SHL 11) DIV 160;
- LineTable[p]^[pos+3]:=(longint(y2-y1) SHL 11) DIV 160;
- inc(pos,4);
-
- dec(z,330);
- end;
-
- {Check if next set of coords should be placed in other buffer, since
- they cannot all fit into one 64Kb segment!!!}
- if ((pos*2 + (LINES*8)) > 65200) then begin
- inc(p);
- pos:=0;
- end;
- inc(angle,1); {calc next angle}
- end;
- end;
-
-
-
- procedure InitDemo;
- var
- i : integer;
- begin
- ClearWholeScreen;
- SetupSinus;
-
- CreateMap;
- CreateTiles;
- SetColours;
- PrecalcLines;
-
- xpos:=200; ypos:=400;
- angle:=0;
- end;
-
- procedure UninitDemo;
- var
- i : integer;
- begin
- FreeMem(map,65535);
- FreeMem(tiles,65535);
- for i:=1 to 3 do FreeMem(LineTable[i],65535);
- end;
-
-
- (*------------------------------------------------*)
-
- procedure MoveHero;
- var
- x,y, sin1,cos1 : integer;
- cx,cy : longint;
- begin
- {Determine new rotation angle}
- ReadMouseMotionCounters(x,y);
- angle:=(angle + x) AND 511;
-
- {is hero moving forward?}
- if (LeftButton) then begin
- sin1:=SinusTable[angle];
- cos1:=SinusTable[angle+128];
- x:=0; {this is the moving speed}
- y:=(5*(retraces+1)) DIV 2;
- cx := (longmul(x,cos1) - longmul(y,sin1)) DIV 32768;
- cy := (longmul(x,sin1) + longmul(y,cos1)) DIV 32768;
- inc(xpos,cx);
- inc(ypos,cy);
- end;
-
- {hero cannot move outside board}
- if (xpos<200) then xpos:=200;
- if (xpos>16384) then xpos:=16384;
- if (ypos<200) then ypos:=200;
- if (ypos>16384) then ypos:=16384;
- end;
-
- (*------------------------------------------------*)
-
- procedure DrawDoom(x,y, angle : integer; Coords : pointer); assembler;
- var
- xadd,yadd,
- mappos : word;
- mapxadd,mapyadd : integer;
- counts : word;
- ceilingtile, flooradd : word;
- colouradd : byte;
- filled : array[0..159] of boolean;
- asm
- push ds
-
- mov es,SEGA000
- mov di,10*320
-
- mov [flooradd],(160*320)-2
- mov [colouradd],0
-
-
- mov ax,WORD PTR [map+2]
- {mov fs,ax} DB $8E,$E0
- mov ax,WORD PTR [Coords+2]
- {mov gs,ax} DB $8E,$E8
- mov ax,WORD PTR [Coords]
- mov [tablepos],ax
-
- cld
- mov [height],LINES
- @y_run:
-
- mov si,[tablepos]
-
- DB GS; mov ax,[si+4]
- cmp [angle],256
- jb @anglelow1
- neg ax
- @anglelow1:
- mov [xadd],ax
- mov [mapxadd],1
- or ax,ax
- jns @mapxup
- mov [mapxadd],-1
- @mapxup:
-
- DB GS; mov ax,[si+6]
- cmp [angle],256
- jb @anglelow2
- neg ax
- @anglelow2:
- mov [yadd],ax
- mov [mapyadd],256
- or ax,ax
- jns @mapyup
- mov [mapyadd],-256
- @mapyup:
-
- DB GS; mov dx,[si]
- DB GS; mov cx,[si+2]
- cmp [angle],256
- jb @anglelow3
- neg cx
- neg dx
- @anglelow3:
- add dx,[x]
- add cx,[y]
-
- mov bx,dx {Find first tile}
- mov ax,cx
- shr ax,5
- shr bx,5
- mov bh,al
- mov [mappos],bx
- DB FS; mov al,[bx+$8000] {get ceiling tile-index from map}
- mov ah,al {find map position in map-buffer}
- and al,7
- shr ah,3
- shl ax,5
- mov [ceilingtile],ax
- DB FS; mov al,[bx] {get floor tile-index from map}
- mov ah,al {find map position in map-buffer}
- and al,7
- shr ah,3
- shl ax,5
- mov si,ax
- sub [ceilingtile],ax
-
- shl dx,11
- shl cx,11
- xor dx,$8000
- xor cx,$8000
-
- mov ds,WORD PTR [tiles+2]
- mov [counts],160
- @x_run:
- mov bh,dh {get x-position of pixel}
- mov bl,ch {get y-position of pixel}
- shr bx,3
- and bx,$1F1F
-
- mov al,[si+bx] {get that pixel}
- add al,[colouradd]
- mov ah,al
- stosw {store ceiling pixels}
- add bx,[ceilingtile]
- mov al,[si+bx] {get that pixel}
- add al,[colouradd]
- mov ah,al
- mov bx,[flooradd]
- mov [es:di+bx],ax {store floor pixels}
-
- add dx,[xadd] {add to x-slope}
- jo @doxadd
- @1:add cx,[yadd] {add to y-slope}
- jo @doyadd
- @2:dec [counts]
- jnz @x_run
- jmp @nextline
-
-
- @doxadd:
- mov bx,[mappos]
- add bx,[mapxadd]
- mov [mappos],bx
- DB FS; mov al,[bx+$8000] {get new ceiling tile-index from map}
- mov ah,al {find tile position in tile-buffer}
- and al,7
- shr ah,3
- shl ax,5
- mov [ceilingtile],ax
- DB FS; mov al,[bx] {get new floor tile-index from map}
- mov ah,al {find tile position in tile-buffer}
- and al,7
- shr ah,3
- shl ax,5
- mov si,ax
- sub [ceilingtile],ax
- jmp NEAR PTR @1
-
- @doyadd:
- mov bx,[mappos]
- add bx,[mapyadd]
- mov [mappos],bx
- DB FS; mov al,[bx+$8000] {get new ceiling tile-index from map}
- mov ah,al {find tile position in tile-buffer}
- and al,7
- shr ah,3
- shl ax,5
- mov [ceilingtile],ax
- DB FS; mov al,[bx] {get new floor tile-index from map}
- mov ah,al {find tile position in tile-buffer}
- and al,7
- shr ah,3
- shl ax,5
- mov si,ax
- sub [ceilingtile],ax
- jmp NEAR PTR @2
-
-
- @nextline:
- mov ax,SEG @DATA
- mov ds,ax
-
- sub [flooradd],320*2
- add [tablepos],8
-
- mov bx,[height]
- mov al,[OFFSET colourtable+bx-1]
- mov [colouradd],al
-
- dec [height]
- jnz @y_run
-
- pop ds
- end;
-
-
- (*------------------------------------------------*)
-
- procedure RunOnce;
- var
- i : integer;
- begin
- while retraces=0 do ;
- retraces:=0;
- {$IFDEF DEBUG} SetRGB(0,20,0,0); {$ENDIF}
- DrawDoom(xpos,ypos, angle, CoordPtr[angle AND 255]);
- MoveHero;
- {$IFDEF DEBUG} SetRGB(0,0,0,0); {$ENDIF}
- end;
-
- begin
- if NOT MouseDriverPresent then begin writeln('No mouse...'); halt; end;
-
- SetScreenMode($13);
- InitDemo;
- SetAllInterrupts;
- repeat RunOnce until Key='e';
- RestoreAllInterrupts;
- UninitDemo;
- SetScreenMode(TEXTMODE);
- end.
-